const url = require('url');
const co = require('co');
const rq = require('request-promise');
const Config = require('config');
const rongCloud = require('rongcloud-sdk');
const logger = require('flogger').getLogger();
const api = require('../constants/constant').api;
const Utility = require('../util/util').Utility;

const models = require('../models');
const User = models.User;
const OnlineStatus = models.OnlineStatus;

rongCloud.init(Config.RONGCLOUD_APP_KEY, Config.RONGCLOUD_APP_SECRET);

function getAndUpdateToken(userId, nickname, portraitUri) {
  return new Promise(function (resolve, reject) {
    return rongCloud.user.getToken(Utility.encodeId(userId), nickname, portraitUri, function (err, resultText) {
      var result;
      if (err) {
        logger.info('获取TOKEN失败', err);
        return reject(err);
      }
      result = JSON.parse(resultText);
      if (result.code !== 200) {
        return reject(new Error('RongCloud Server API Error Code: ' + result.code));
      }
      return User.update({
        rongCloudToken: result.token
      }, {
          where: {
            id: userId
          }
        }).then(function () {
          return resolve(result.token);
        });
    });
  });
}

// 注册用户
module.exports.findOrRegister = function (uid) {
  return co(function* () {

    // 1. 查找用户
    // 2. 如果用户不存在，从服务器获取用户信息，创建用户
    // 3. 同步组信息
    // 4. 如果rongCloudToken不存在，获取并更新token
    // 5. 返回用户信息

    var user = yield User.findOne({
      where: {
        uid: uid
      },
      attributes: ['id', 'uid', 'nickname', 'contactNumber', 'storeName', 'storeId', 'partyGroup', 'portraitUri', 'rongCloudToken']
    });

    logger.info(`查找用户${uid}的信息`, JSON.stringify(user));

    if (!user) {
      // 从服务器获取用户信息
      var userInfoOptions = {
        method: 'POST',
        uri: url.resolve(Config.ORIGINAL, api.USER_INFO_API),
        form: {
          userLoginId: uid
        },
        transform: function (body) {
          logger.info(`获取${uid}的用户信息`, body);
          if (typeof body === 'string') {
            return (JSON.parse(body)).result;
          }
        }
      };
      logger.info(`从服务器获取 ${uid} 的用户信息`, userInfoOptions);
      let userinfo = yield rq(userInfoOptions);
      logger.info(`用户 ${uid} 的信息为`, userinfo);

      // 创建用户
      yield User.create({
        uid: uid,
        nickname: userinfo.userName,
        partyGroup: userinfo.partyGrpoup,
        contactNumber: userinfo.contactNumber,
        storeName: userinfo.storeName,
        storeId: userinfo.productStoreId,
        position: ''
      });

      logger.info(`完成新用户${uid}的创建`);

      // 重新查询用户
      user = yield User.findOne({
        where: {
          uid: uid
        },
        attributes: ['id', 'uid', 'nickname', 'contactNumber', 'storeName', 'storeId', 'partyGroup', 'portraitUri', 'rongCloudToken']
      });
    }

    var token = user.rongCloudToken;
    if (!token) {
      token = yield getAndUpdateToken(user.id, user.nickname, user.portraitUri);
      user.rongCloudToken = token;
    }
    return user;
  });
};

// 批量查询用户的在线状态，如果过期，刷新
module.exports.findAndUpdateUsersOnlineStatus = function (ids, expires) {
  // 1. 从数据库批量拉取
  // 2. 如果没有，从融云拉取
  // 3. 如果设置了过期时间，过期时间之前的重新从融云拉取
  return co(function* () {
    let statuses = yield OnlineStatus.findAll({
      where: {
        userId: {
          $in: ids
        }
      },
      attributes: ['userId', 'os', 'timestamp', 'status']
    });

    // 转换成JSON
    statuses = statuses.map(status => status.toJSON());

    // 数据库缺少的id
    let missIds = ids.filter(id => {
      return !statuses.some(status => status.userId === id);
    });

    // 查找数据库没有的用户在线状态
    for (let id of missIds) {
      let status = yield getAndUpdateOnlineStatus(id);
      statuses.push(status);
    }
    
    // 如果设置了过期时间，过期时间之前的重新从融云拉取
    if (expires) {
      for (let status of statuses) {
        if (status.timestamp < expires) {
          let result = yield getAndUpdateOnlineStatus(status.userId);
          Object.assign(status, result);
        }
      }
    }
    return statuses;
  });
}

// 更新并返回用户的在线状态
function getAndUpdateOnlineStatus(userId) {
  return new Promise((resolve, reject) => {
    rongCloud.user.checkOnline(Utility.numberToString(userId), function (err, result) {
      if (err) {
        logger.warn(`查询用户 ${userId} 在线状态错误`);
        return reject(err);
      }

      // 查询到的是字符串，需要parse
      let statusCode = JSON.parse(result);
      logger.info(`获取到用户 ${userId} 的在线状态`, statusCode);

      let status = {
        userId: userId,
        status: parseInt(statusCode.status) ? 0 : 1,    // 主动检测在线状态刚好和订阅的在线状态相反1为在线，0为离线
        os: '',
        timestamp: parseInt(new Date().getTime())
      };

      logger.info(`获取到用户 ${userId} 的在线状态`, status);

      // 保存到数据库
      OnlineStatus.upsert(status).then(()=>resolve(status));
    });
  });
}

module.exports.getAndUpdateToken = getAndUpdateToken;
